package flc.ast.utils;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

// 添加Android主线程相关导入
import android.os.Handler;
import android.os.Looper;

import com.blankj.utilcode.util.ToastUtils;

public class UDPServer {
    private DatagramSocket serverSocket;
    private ExecutorService threadPool = Executors.newCachedThreadPool();
    private boolean isRunning = true;
    private MessageListener messageListener;
    // 存储活跃客户端地址
    private List<InetSocketAddress> clientAddresses = new ArrayList<>();
    // 将ScheduledExecutorService替换为Android主线程Handler
    private Handler mainHandler = new Handler(Looper.getMainLooper());
    private String receiveCharsetName = "UTF-8"; // 默认接收字符编码
    private String sendCharsetName = "UTF-8"; // 默认发送字符编码
    private int bufferSize = 1024; // 默认缓冲区大小

    // 统计信息
    private int receivedCount = 0;        // 接收消息计数
    private int sentCount = 0;            // 发送消息计数
    private long receivedBytes = 0;       // 接收总字节数
    private long sentBytes = 0;           // 发送总字节数
    private long startTime = 0;           // 开始统计时间
    private int failedCount = 0;          // 失败次数

    // 消息回调接口
    public interface MessageListener {
        void onMessageReceived(String message);

        void onClientActivity(String ip); // UDP无连接，改为客户端活动通知

        void onStatisticsUpdated(int receivedCount, int sentCount, double receiveSpeed, double sendSpeed, int failedCount);
    }

    // 设置消息监听器
    public void setMessageListener(MessageListener listener) {
        this.messageListener = listener;
    }

    // 设置字符编码（同时设置接收和发送）
    public void setCharsetName(String charsetName) {
        this.receiveCharsetName = charsetName;
        this.sendCharsetName = charsetName;
    }

    // 设置接收字符编码
    public void setReceiveCharsetName(String receiveCharsetName) {
        this.receiveCharsetName = receiveCharsetName;
    }

    // 设置发送字符编码
    public void setSendCharsetName(String sendCharsetName) {
        this.sendCharsetName = sendCharsetName;
    }

    // 设置缓冲区大小
    public void setBufferSize(int bufferSize) {
        this.bufferSize = bufferSize;
    }

    public void start(int port) {
        try {
            serverSocket = new DatagramSocket(null);
            serverSocket.setReuseAddress(true);
            serverSocket.bind(new InetSocketAddress(port));
            startTime = System.currentTimeMillis();

            new Thread(() -> {
                byte[] buffer = new byte[bufferSize];
                while (isRunning && !serverSocket.isClosed()) {
                    try {
                        DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
                        serverSocket.receive(packet);
                        handleReceivedPacket(packet);
                    } catch (IOException e) {
                        if (isRunning) {
                            e.printStackTrace();
                            failedCount++;
                            updateStatistics();
                        }
                    }
                }
            }).start();
        } catch (SocketException e) {
            throw new RuntimeException(e);
        }
    }

    private void handleReceivedPacket(DatagramPacket packet) {
        threadPool.execute(() -> {
            try {
                InetSocketAddress clientAddress = new InetSocketAddress(packet.getAddress(), packet.getPort());
                String clientIp = clientAddress.getAddress().getHostAddress();
                int clientPort = clientAddress.getPort();
                String senderInfo = "[" + clientIp + ":" + clientPort + "]";

//                notifyClientActivity(senderInfo);

                // 更新客户端列表
                if (updateClientList(clientAddress)) {
                    // 处理接收到的数据
                    String message = new String(packet.getData(), 0, packet.getLength(), Charset.forName(receiveCharsetName));
                    message = senderInfo + message;
                    System.out.println("Received: " + message);

                    // 更新统计信息
                    receivedCount++;
                    receivedBytes += packet.getLength();
                    notifyMessageReceived(message);
                    updateStatistics();
                }
            } catch (Exception e) {
                e.printStackTrace();
                failedCount++;
                updateStatistics();
            }
        });
    }

    private boolean updateClientList(InetSocketAddress clientAddress) {
        synchronized (clientAddresses) {
            // 如果客户端不在列表中则添加
            if (!clientAddresses.contains(clientAddress)) {
                clientAddresses.add(clientAddress);
                return false;
            }
            return true;
        }
    }

    // 发送消息到指定地址
    public void sendMessage(InetAddress address, int port, String message) {
        if (serverSocket == null || serverSocket.isClosed()) return;

        threadPool.execute(() -> {
            try {
                byte[] data = message.getBytes(Charset.forName(sendCharsetName));
                DatagramPacket packet = new DatagramPacket(data, data.length, address, port);
                serverSocket.send(packet);

                // 更新统计信息
                sentCount++;
                sentBytes += data.length;
                updateStatistics();
            } catch (IOException e) {
                e.printStackTrace();
                failedCount++;
                updateStatistics();
            }
        });
    }

    // 向所有已知客户端发送消息
    public void sendMessageToAllClients(String message) {
        synchronized (clientAddresses) {
            for (InetSocketAddress address : clientAddresses) {
                sendMessage(address.getAddress(), address.getPort(), message);
            }
        }
    }

    // 向特定IP的客户端发送消息
    public void sendMessageToClient(String ip, String message) {
        synchronized (clientAddresses) {
            for (InetSocketAddress address : clientAddresses) {
                if (address.getAddress().getHostAddress().equals(ip)) {
                    sendMessage(address.getAddress(), address.getPort(), message);
                    break;
                }
            }
        }
    }

    // 通知接收到消息
    private void notifyMessageReceived(final String message) {
        if (messageListener != null) {
            mainHandler.post(() -> messageListener.onMessageReceived(message));
        }
    }

    // 通知客户端活动
    private void notifyClientActivity(String ip) {
        if (messageListener != null) {
            mainHandler.post(() -> messageListener.onClientActivity(ip));
        }
    }

    // 更新统计信息
    private void updateStatistics() {
        if (messageListener == null) return;

        long currentTime = System.currentTimeMillis();
        double elapsedTime = (currentTime - startTime) / 1000.0; // 秒

        double receiveSpeed = elapsedTime > 0 ? receivedBytes / elapsedTime : 0; // B/s
        double sendSpeed = elapsedTime > 0 ? sentBytes / elapsedTime : 0; // B/s

        mainHandler.post(() -> messageListener.onStatisticsUpdated(
                receivedCount, sentCount, receiveSpeed, sendSpeed, failedCount));
    }

    public void stop() {
        isRunning = false;
        threadPool.shutdown();
        // 移除ScheduledExecutorService的shutdown调用
        if (serverSocket != null && !serverSocket.isClosed()) {
            serverSocket.close();
        }
        synchronized (clientAddresses) {
            clientAddresses.clear();
        }
    }
}